package com.central.apps.controller;

import com.alibaba.fastjson.JSONObject;
import com.central.app.service.HandlerService;
import com.central.common.web.Result;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;

/**
 * 项目管理接口类
 *
 * @author 李大超
 * @date 2022/9/13
 */
@RestController
@Api(tags = "项目管理接口类")
@RequestMapping("/project")
@Slf4j
public class ProjectController {

    @Autowired
    private HandlerService handlerService;

    /**
     * 获取项目来源比例数据（饼图）
     */
    @GetMapping("/getProSource")
    public Result getProSource() {
        List<Map<String, Object>> list = handlerService.findBySql("select prosource as name, count(id) as value from gq_proaccount group by prosource");
        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取项目状态对应项目数
     */
    @GetMapping("/getProStatus")
    public Result getProStatus() {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<String> statusList = Arrays.asList("立项中", "进行中", "已完成");
        List<Map<String, Object>> list = handlerService.findBySql("select prostatus, count(id) as proCount from (select id, '立项中' as prostatus from gq_establishproject where status not in ('立项完成','已作废') union all select id, prostatus from gq_proaccount) t group by prostatus");

        for (String status : statusList) {
            Map<String, Object> resultMap = new HashMap<>();
            for (Map<String, Object> map : list) {
                String proStatus = MapUtils.getString(map, "prostatus");
                if (status.equals(proStatus)) {
                    resultMap.put("name", status);
                    resultMap.put("value", MapUtils.getInteger(map, "proCount"));
                }
            }

            if (ObjectUtils.isEmpty(resultMap)) {
                resultMap.put("name", status);
                resultMap.put("value", 0);
            }

            resultList.add(resultMap);
        }
        return Result.succeedWith(resultList, 0, "查询成功");
    }

    /**
     * 获取存在风险项目
     */
    @GetMapping("/getRiskPro")
    public Result getRiskPro() {
        List<Map<String, Object>> list = handlerService.findBySql("select subjectno, (case when proschedulestatus != '按期进行' and costexestatus != '按期进行' then CONCAT(proschedulestatus,';',costexestatus)" +
                " when proschedulestatus = '按期进行' and costexestatus != '按期进行' then costexestatus" +
                " else proschedulestatus end) as status, (case when proschedulestatus != '按期进行' and costexestatus != '按期进行' then '高' " +
                " else '中' end) as riskLevel from gq_proaccount where proschedulestatus != '按期进行' or costexestatus != '按期进行' order by subjectno desc");

        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取项目概算排行前10(柱状图横向)
     */
    @GetMapping("/getProRank")
    public Result getProRank() {
        List<Map<String, Object>> list = handlerService.findBySql("SELECT t.subjectno, t.amount FROM (select sum(budgetamt) as amount, subjectno from gq_pblbestimate where subjectno is not null group by subjectno) t ORDER BY t.amount desc LIMIT 10");
        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取任务量（环形饼图）
     */
    @GetMapping("/getTaskCount")
    public Result getTaskCount() {
        List<Map<String, Object>> list = handlerService.findBySql("select a.name, count(t.id) as count from (select code, name from sys_dict c where c.pid = 387) a left join (select DATE_FORMAT(startTime, '%c') as month, id from gq_scheduleplantask) t\n" +
                " on t.month = a.code group by a.name, a.code order by cast(code as signed)");

        Map<String, List<Object>> resultMap = new HashMap<>(2);
        List<Object> xList = new ArrayList<>();
        List<Object> yList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("name".equals(entry.getKey())) {
                    xList.add(entry.getValue());
                } else {
                    yList.add(entry.getValue());
                }
            }
        }

        resultMap.put("x", xList);
        resultMap.put("y", yList);

        return Result.succeedWith(resultMap, 0, "查询成功");
    }

    /**
     * 获取成本费用(柱状图纵向)
     */
    @GetMapping("/getProCost")
    public Result getProCost() {
        List<Map<String, Object>> list = handlerService.findBySql("select t.itemdesc, ifnull(a.amount, 0) as amount from gq_probugdetcfg t left join (select pbiid, sum(budgetamt) as amount from gq_pblbestimate group by pbiid) a on t.id = a.pbiid where parentitemnum = 'project_budget' and status = '可用' order by sortno");

        Map<String, List<Object>> resultMap = new HashMap<>(2);
        List<Object> xList = new ArrayList<>();
        List<Object> yList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("itemdesc".equals(entry.getKey())) {
                    xList.add(entry.getValue());
                } else {
                    yList.add(entry.getValue());
                }
            }
        }

        resultMap.put("x", xList);
        resultMap.put("y", yList);

        return Result.succeedWith(resultMap, 0, "查询成功");
    }

    /**
     * 获取项目执行情况（折线图）
     */
    @GetMapping("/getProProgress")
    public Result getProProgress(Integer proId) {
        List<Map<String, Object>> list = handlerService.findBySql("select concat(s.year, '年', b.code, '月') as yearMonth , round(s.planDuration / a.totalDuration * 100, 1) as planProgress, round(s.actualDuration / a.totalDuration * 100, 1) as actualProgress from (select t.proid, DATE_FORMAT(t.endTime, '%Y') as year, DATE_FORMAT(t.endTime, '%c') as month, sum(t.duration) as planDuration, sum(t.progress * t.duration) as actualDuration " +
                " from gq_pblmilestone t where proid = " + proId + " group by DATE_FORMAT(t.endTime, '%Y'), DATE_FORMAT(t.endTime, '%c')) s left join (select sum(duration) as totalDuration, proid from gq_pblmilestone where proid = " + proId + " group by proid) a on a.proid = s.proid " +
                " left join (select code, name from sys_dict c where c.pid = 387) b on s.month = b.code where s.proid = " + proId + " order by s.year, cast(code as signed) ");

        Map<String, List<Object>> resultMap = new HashMap<>(2);
        List<Object> xList = new ArrayList<>();
        List<Object> y1List = new ArrayList<>();
        List<Object> y2List = new ArrayList<>();
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("yearMonth".equals(entry.getKey())) {
                    xList.add(entry.getValue());
                } else if ("planProgress".equals(entry.getKey())) {
                    y1List.add(entry.getValue());
                } else {
                    y2List.add(entry.getValue());
                }
            }
        }

        resultMap.put("x", xList);
        resultMap.put("y1", y1List);
        resultMap.put("y2", y2List);

        return Result.succeedWith(resultMap, 0, "查询成功");
    }

    /**
     * 获取任务数据（环形饼图）
     */
    @GetMapping("/getTask")
    public Result getTask(Integer proId) {
        List<Map<String, Object>> list = handlerService.findBySql("select status as name, count(id) as value from gq_scheduleplantask where proid = " + proId + " group by status");
        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取任务交付物数据（环形饼图）
     */
    @GetMapping("/getDeli")
    public Result getDeli(Integer proId) {
        List<Map<String, Object>> list = handlerService.findBySql("select status as name, count(id) as value from gq_taskdeliverables where proid = " + proId + " group by status");
        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取里程碑数据（关系图）
     */
    @GetMapping("/getMileStone")
    public Result getMileStone(Integer proId) {
        List<Map<String, Object>> list = handlerService.findBySql("select name, status from gq_pblmilestone where proid = " + proId + " order by startTime");
        return Result.succeedWith(list, 0, "查询成功");
    }

    /**
     * 获取预算执行(柱状图带对比)
     */
    @GetMapping("/getBudget")
    public Result getBudget(Integer proId) {
        List<Map<String, Object>> list = handlerService.findBySql("select budgetamt, actualamt, budgetitem from gq_pblbestimate where proid = " + proId + " order by id");

        Map<String, List<Object>> resultMap = new HashMap<>(2);
        List<Object> xList = new ArrayList<>();
        List<Object> y1List = new ArrayList<>();
        List<Object> y2List = new ArrayList<>();
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("budgetitem".equals(entry.getKey())) {
                    xList.add(entry.getValue());
                } else if ("budgetamt".equals(entry.getKey())) {
                    y1List.add(entry.getValue());
                } else {
                    y2List.add(entry.getValue());
                }
            }
        }

        resultMap.put("x", xList);
        resultMap.put("y1", y1List);
        resultMap.put("y2", y2List);

        return Result.succeedWith(resultMap, 0, "查询成功");
    }

    @PostMapping("/tree")
    public String findTree(String pronum, String proname) {
        JSONObject jsonObj = new JSONObject();
        StringBuilder sbSql = new StringBuilder();
        sbSql.append("select * from gq_proaccount where 1 = 1");
        if (StringUtils.isNotEmpty(pronum)) {
            sbSql.append(" and pronum = '" + pronum + "'");
        }
        if (StringUtils.isNotEmpty(proname)) {
            sbSql.append(" and proname like '%" + proname + "%'");
        }
        if (StringUtils.isEmpty(pronum) && StringUtils.isEmpty(proname)) {
            sbSql.append(" and proparentid is null");
        }
        sbSql.append(" order by pronum desc LIMIT 0, 10");
        List<Map<String, Object>> proList = handlerService.findBySql(sbSql.toString());

        if (CollectionUtils.isNotEmpty(proList)) {
            jsonObj.put("data", proList);
            // 递归查询树形数据
            recursiveQuery(proList);
        }

        return jsonObj.toJSONString();
    }

    /**
     * 递归查询树形数据
     *
     * @param parentList
     */
    private void recursiveQuery(List<Map<String, Object>> parentList) {
        for (Map<String, Object> parentMap : parentList) {
            int id = (int) parentMap.get("id");

            // 查询树形子数据
            List<Map<String, Object>> childList = handlerService.findBySql("select * from gq_proaccount where proparentid = " + id);

            if (CollectionUtils.isNotEmpty(childList)) {
                parentMap.put("children", childList);
                // 递归树形子数据
                recursiveQuery(childList);
            }
        }
    }
}
